import store from '../store'

import { baseUrl } from '@/utils/config'
export default class SocketService {
    /* 单例模式 */
    static instance = null
    static get Instance() {
        if (!this.instance) {
            this.instance = new SocketService()
        }
        return this.instance
    }
    // 和服务端连接的socket对象
    ws = null
    // 存储回调函数
    callBackMapping = {}

    // 标识是否连接成功
    connected = false

    // 记录重试的次数
    sendRetryCount = 0

    // 重新连接尝试的次数
    connectRetryCount = 0
    // 定义是否关闭ws连接
    isClosed = true

    // 定义连接服务器的方法
    connect() {
        /*   if (!Window.WebSocket) {
            return console.log('您的浏览器不支持WebSocket')
          } */
        this.ws = new WebSocket(`ws://${baseUrl}/WebSocket/1`) // Websocket ip+端口
        // 连接成功
        this.ws.onopen = () => {
            Message.success('WebSocket连接成功')
            heartCheck.reset().start()
            this.connected = true
            this.isClosed = false
            // 重置重新连接的次数
            this.connectRetryCount = 0
        }
        // 连接失败
        this.ws.onclose = () => {
            if (this.isClosed) {
                return false
            } else {
                Message.error('服务器连接失败')
                this.connected = false
                this.connectRetryCount++
                setTimeout(() => {
                    this.connect()
                }, 500 * this.connectRetryCount)
            }
        }
        // 接收数据
        this.ws.onmessage = msg => {
            store.dispatch('setDataPageData', JSON.parse(msg.data)).then()
        }
    }



    // 发送数据的方法
    send(data) {
        // 判断此时此刻有没有连接成功
        if (this.connected) {
            this.sendRetryCount = 0
            this.ws.send(JSON.stringify(data))
        } else {
            this.sendRetryCount++
            setTimeout(() => {
                this.send(data)
            }, this.sendRetryCount * 500)
        }
    }

    // webSocket的关闭  用于vue销毁生命周期
    close() {
        if (this.ws) {
            this.isClosed = true
            this.ws.close() // 关闭websocket
            Message.info('websocket已关闭')
            heartCheck.reset()// 心跳检测
        }
    }

    // 回调函数的注册
    registerCallBack(socketType, callBack) {
        this.callBackMapping[socketType] = callBack
    }

    // 取消某一个回调函数
    unRegisterCallBack(socketType) {
        this.callBackMapping[socketType] = null
    }
}
/**
     * websocket心跳检测
     */
const heartCheck = {
    timeout: 5000,
    timeoutObj: null,
    serverTimeoutObj: null,
    reset: function () {
        clearTimeout(this.timeoutObj)
        clearTimeout(this.serverTimeoutObj)
        return this
    },
    start: function () {
        const self = this
        this.timeoutObj && clearTimeout(this.timeoutObj)
        this.serverTimeoutObj && clearTimeout(this.serverTimeoutObj)
        this.timeoutObj = setTimeout(function () {
            // 这里发送一个心跳，后端收到后，返回一个心跳消息，
            // onmessage拿到返回的心跳就说明连接正常
            SocketService.Instance.ws.send('I am Your father！')
            // Message.info('HeartBeat')
            self.serverTimeoutObj = setTimeout(function () { // 如果超过一定时间还没重置，说明后端主动断开了
                Message.warning('关闭服务')
                SocketService.Instance.ws.close()// 如果onclose会执行reconnect，我们执行 websocket.close()就行了.如果直接执行 reconnect 会触发onclose导致重连两次
            }, self.timeout)
        }, this.timeout)
    }
}
